<?php
/**
 * Dispatcher
 * 
 * 单例模式
 * 单入口模式，发报器
 *
 * @author   songhuan <iphper@yeah.net>
 * @version   $Id: Dispatcher.php 1 2010-08-10 14:40:00Z $
 */
class Dispatcher
{
	private static $_instance = null;

	/**
	 * @var Request URL请求模式处理
	 */
	protected $_request = null;
	
	/**
	 * @var string 控制器类名
	 */
    private $_controller = null;
    
    /**
	 * @var string 控制器默认后缀
	 */
    private $_controllerKey = null;

    /**
	 * @var string 方法名
	 */
    private $_action = null;
    
    /**
	 * @var string 方法名默认后缀
	 */
    private $_actionKey = null;

    /**
	 * @var string 如果方法名为空，默认调用的方法名
	 */
    private $_defaultAction = null;
    
    /**
	 * @var string 如果控制器类名为空，默认调用的类名
	 */
    private $_defaultController = null;

    /**
	 * @var string 控制器类所在的路径
	 */
	private $_controllerDirectory = null;
	
	/**
	 * @var Object 模板引擎
	 */
	private $_view = null;
	
	/**
	 * 初始化$_controller, $_action值
	 * 并从配置获取$_controllerKey, $_actionKey, $_defaultAction, $_defaultController, $_controllerDirectory的值
	 */
	private function __construct()
    {
		$this->_request = Request::getInstance();
		
		$this->_controllerDirectory = V::$config['controller']['controllerDirectory'];
		
		$this->_defaultAction = V::$config['controller']['defaultAction'];
		$this->_action = $this->_request->getAction() ? 
			$this->_request->getAction() : $this->_defaultAction;
			
        $this->_defaultController = V::$config['controller']['defaultController'];
		$this->_controller = $this->_request->getController() ? 
			$this->_request->getController() : $this->_defaultController;
			
		$this->_actionKey = V::$config['controller']['actionKey'];
		$this->_controllerKey = V::$config['controller']['controllerKey'];
    }
    
    private function __clone() 
    {
    }

	public static function getInstance()
    {
        if (null === self::$_instance) 
            self::$_instance = new self();

        return self::$_instance;
    }
	
    /**
     * 实例化Controller类，调用action方法
     */
	public function run()
	{	
		$controller = $this->getControllerClass();
		$dir = $this->_controllerDirectory . DS . $controller . '.php';
		if (file_exists($dir)) 
		{
			require_once 'Controller.php';
			require_once $dir;
			if (class_exists($controller)) 
			{
				$class = new $controller($this);
				if ($class instanceof Controller) 
				{
					$method = $this->getActionMethod();
					if (method_exists($class, $method)) 
					{
						$class->preDispatch();
						$class->$method();
						$class->postDispatch();
					}
					else 
						throw new Exception('Method Action "' . $method . '" Is Not Exists');
				}
				else 
					throw new Exception('Class Controller "' . $controller . '" Is Not Instanceof Controller');
			}
			else 
				throw new Exception('Class Controller "' . $controller . '" Is Not Exists');
		}
		else 
			throw new Exception('Controller File "' . $dir . '" Is Not Exists');
	}
	
	/**
	 * @return string Controller名
	 */
	public function getControllerClass()
	{
		return ucfirst(strtolower($this->_controller)) . $this->_controllerKey;
	}
	
	/**
	 * @return string Action名
	 */
	public function getActionMethod()
	{
		return strtolower($this->_action) . $this->_actionKey;
	}

	public function __get($name)
	{
		return $this->$name;
	}

	public function __set($name, $value) 
	{
		$this->$name = $value;
	}
	
	/**
	 * 设置Controller所在路径
	 * 
	 * @param string $controllerDirectory
	 * @return Object $this
	 */
	public function setControllerDirectory($controllerDirectory)
	{
		$this->_controllerDirectory = $controllerDirectory;
		return $this;
	}
}
